#!/usr/bin/env lua
-- Lua Battle System - AI性能测试框架
-- 专门用于测试AI系统性能和决策质量的综合测试框架

-- 设置Lua路径
package.path = package.path .. ';src/?.lua;src/utils/?.lua;tests/?.lua;tests/unit/?.lua'

local TestFramework = require("src.utils.test_framework")
local Logger = require("utils.logger")
local TacticalAI = require("ai.tactical_ai")
local DecisionMaker = require("ai.decision_maker")
local BattleManager = require("battle.battle_manager")

local AIPerformanceTest = {
    -- 测试配置
    config = {
        test_scenarios = 100,     -- 测试场景数量
        decision_timeout = 100,   -- 决策超时时间（毫秒）
        performance_threshold = 50, -- 性能阈值（毫秒）
        memory_leak_threshold = 1024 * 1024, -- 内存泄漏阈值（1MB）

        -- AI难度级别测试
        difficulty_levels = {"easy", "normal", "hard", "expert"},

        -- 战斗规模测试
        battle_scales = {
            small = {players = 2, enemies = 2},
            medium = {players = 4, enemies = 4},
            large = {players = 6, enemies = 8}
        }
    },

    -- 性能监控器
    performance_monitor = {
        start_time = 0,
        end_time = 0,
        memory_usage = {},
        decision_times = {},
        cpu_usage = {}
    }
}

-- AI性能测试套件
local suite = TestFramework.TestSuite.new("AI系统性能测试")

-- 测试1：AI决策响应时间测试
function AIPerformanceTest.test_decision_response_time()
    print("🧪 开始AI决策响应时间测试...")

    local test_results = {
        total_tests = 0,
        passed_tests = 0,
        avg_response_time = 0,
        max_response_time = 0,
        min_response_time = math.huge,
        timeout_count = 0
    }

    local total_time = 0

    for i = 1, AIPerformanceTest.config.test_scenarios do
        -- 创建测试战斗场景
        local battle_state = AIPerformanceTest:create_test_battle_state()
        local character = battle_state.characters[1] -- 假设第一个是AI角色
        local ai = TacticalAI:new()

        -- 开始性能监控
        local start_time = os.clock()

        -- 执行AI决策
        local decision = ai:make_decision(character, battle_state)

        -- 结束性能监控
        local end_time = os.clock()
        local response_time = (end_time - start_time) * 1000 -- 转换为毫秒

        -- 更新统计信息
        total_time = total_time + response_time
        test_results.total_tests = test_results.total_tests + 1

        if response_time > AIPerformanceTest.config.decision_timeout then
            test_results.timeout_count = test_results.timeout_count + 1
        elseif response_time <= AIPerformanceTest.config.performance_threshold then
            test_results.passed_tests = test_results.passed_tests + 1
        end

        test_results.max_response_time = math.max(test_results.max_response_time, response_time)
        test_results.min_response_time = math.min(test_results.min_response_time, response_time)

        -- 验证决策有效性
        if decision then
            test_results.passed_tests = test_results.passed_tests + 1
        end
    end

    test_results.avg_response_time = total_time / test_results.total_tests

    -- 生成测试报告
    local report = string.format([[
AI决策响应时间测试报告
- 总测试场景: %d
- 通过测试: %d (%.1f%%)
- 超时场景: %d
- 平均响应时间: %.2fms
- 最大响应时间: %.2fms
- 最小响应时间: %.2fms
- 性能阈值: %dms
    ]],
        test_results.total_tests,
        test_results.passed_tests,
        (test_results.passed_tests / test_results.total_tests) * 100,
        test_results.timeout_count,
        test_results.avg_response_time,
        test_results.max_response_time,
        test_results.min_response_time,
        AIPerformanceTest.config.performance_threshold
    )

    print(report)

    -- 断言验证
    if not (test_results.avg_response_time <= AIPerformanceTest.config.performance_threshold) then
        error(string.format("平均响应时间 %.2fms 超过阈值 %dms", test_results.avg_response_time, AIPerformanceTest.config.performance_threshold))
    end

    if not (test_results.timeout_count < test_results.total_tests * 0.1) then
        error("超时场景过多: " .. test_results.timeout_count)
    end

    return test_results
end

-- 测试2：AI决策质量评估
function AIPerformanceTest.test_decision_quality()
    print("🧠 开始AI决策质量评估测试...")

    local quality_results = {
        total_tests = 0,
        good_decisions = 0,
        bad_decisions = 0,
        avg_decision_score = 0,
        strategic_correctness = 0,
        efficiency_score = 0
    }

    local total_score = 0
    local strategic_correct_count = 0

    for i = 1, 50 do -- 质量测试场景较少，但更详细
        local battle_state = AIPerformanceTest:create_test_battle_state()
        local character = battle_state.characters[1]
        local ai = TacticalAI:new()

        -- 记录决策前的战斗状态
        local pre_battle_state = AIPerformanceTest:deep_copy_battle_state(battle_state)

        -- 执行AI决策
        local decision = ai:make_decision(character, battle_state)

        -- 评估决策质量
        local quality_score = AIPerformanceTest:evaluate_decision_quality(pre_battle_state, decision, character)

        total_score = total_score + quality_score
        quality_results.total_tests = quality_results.total_tests + 1

        if quality_score >= 70 then
            quality_results.good_decisions = quality_results.good_decisions + 1
        else
            quality_results.bad_decisions = quality_results.bad_decisions + 1
        end

        -- 评估战略正确性
        if AIPerformanceTest:is_strategically_correct(pre_battle_state, decision) then
            strategic_correct_count = strategic_correct_count + 1
        end
    end

    quality_results.avg_decision_score = total_score / quality_results.total_tests
    quality_results.strategic_correctness = (strategic_correct_count / quality_results.total_tests) * 100
    quality_results.efficiency_score = quality_results.avg_decision_score * 0.8 + quality_results.strategic_correctness * 0.2

    -- 生成质量报告
    local quality_report = string.format([[
AI决策质量评估报告
- 总评估场景: %d
- 优秀决策: %d (%.1f%%)
- 较差决策: %d (%.1f%%)
- 平均决策评分: %.1f/100
- 战略正确率: %.1f%%
- 综合效率评分: %.1f/100
    ]],
        quality_results.total_tests,
        quality_results.good_decisions,
        (quality_results.good_decisions / quality_results.total_tests) * 100,
        quality_results.bad_decisions,
        (quality_results.bad_decisions / quality_results.total_tests) * 100,
        quality_results.avg_decision_score,
        quality_results.strategic_correctness,
        quality_results.efficiency_score
    )

    print(quality_report)

    -- 断言验证
    if not (quality_results.avg_decision_score >= 60) then
        error("平均决策评分过低: " .. quality_results.avg_decision_score)
    end

    if not (quality_results.strategic_correctness >= 70) then
        error("战略正确率过低: " .. quality_results.strategic_correctness)
    end

    return quality_results
end

-- 测试3：内存泄漏检测
function AIPerformanceTest.test_memory_leaks()
    print("🔍 开始内存泄漏检测测试...")

    local initial_memory = collectgarbage("count")

    -- 执行大量AI决策操作
    for i = 1, 1000 do
        local battle_state = AIPerformanceTest:create_test_battle_state()
        local character = battle_state.characters[1]
        local ai = TacticalAI:new()

        -- 执行决策
        local decision = ai:make_decision(character, battle_state)

        -- 强制垃圾回收（每100次）
        if i % 100 == 0 then
            collectgarbage("collect")
        end
    end

    -- 最终垃圾回收
    collectgarbage("collect")
    collectgarbage("collect") -- 双重回收确保完整性

    local final_memory = collectgarbage("count")
    local memory_increase = final_memory - initial_memory

    local memory_report = string.format([[
内存泄漏检测报告
- 初始内存使用: %.2f KB
- 最终内存使用: %.2f KB
- 内存增长量: %.2f KB
- 内存泄漏阈值: %.2f KB
    ]],
        initial_memory,
        final_memory,
        memory_increase,
        AIPerformanceTest.config.memory_leak_threshold / 1024
    )

    print(memory_report)

    -- 断言验证
    if not (memory_increase <= AIPerformanceTest.config.memory_leak_threshold / 1024) then
        error(string.format("检测到内存泄漏: %.2f KB 超过阈值", memory_increase))
    end

    return {
        initial_memory = initial_memory,
        final_memory = final_memory,
        memory_increase = memory_increase,
        has_leak = memory_increase > AIPerformanceTest.config.memory_leak_threshold / 1024
    }
end

-- 测试4：不同难度级别性能对比
function AIPerformanceTest.test_difficulty_performance()
    print("⚡ 开始不同难度级别性能对比测试...")

    local difficulty_results = {}

    for _, difficulty in ipairs(AIPerformanceTest.config.difficulty_levels) do
        local total_time = 0
        local decision_count = 0
        local quality_scores = {}

        for i = 1, 30 do -- 每个难度30次测试
            local battle_state = AIPerformanceTest:create_test_battle_state()
            local character = battle_state.characters[1]
            local ai = TacticalAI:new({difficulty = difficulty})

            -- 性能测试
            local start_time = os.clock()
            local decision = ai:make_decision(character, battle_state)
            local end_time = os.clock()

            local response_time = (end_time - start_time) * 1000
            total_time = total_time + response_time
            decision_count = decision_count + 1

            -- 质量评估
            local quality_score = AIPerformanceTest:evaluate_decision_quality(battle_state, decision, character)
            table.insert(quality_scores, quality_score)
        end

        local avg_time = total_time / decision_count
        local avg_quality = 0
        for _, score in ipairs(quality_scores) do
            avg_quality = avg_quality + score
        end
        avg_quality = avg_quality / #quality_scores

        difficulty_results[difficulty] = {
            avg_response_time = avg_time,
            avg_quality_score = avg_quality,
            test_count = decision_count
        }
    end

    -- 生成难度对比报告
    local difficulty_report = "难度级别性能对比报告:\n"
    for difficulty, results in pairs(difficulty_results) do
        difficulty_report = difficulty_report .. string.format(
            "- %s: 响应时间 %.2fms, 质量评分 %.1f/100\n",
            difficulty, results.avg_response_time, results.avg_quality_score
        )
    end

    print(difficulty_report)

    -- 验证性能随难度的合理性
    if not (difficulty_results.easy.avg_response_time <= difficulty_results.expert.avg_response_time * 1.5) then
        error("简单难度响应时间不应显著高于专家难度")
    end

    if not (difficulty_results.expert.avg_quality_score >= difficulty_results.easy.avg_quality_score) then
        error("专家难度质量评分应不低于简单难度")
    end

    return difficulty_results
end

-- 测试5：大规模战斗AI性能
function AIPerformanceTest.test_large_scale_performance()
    print("🏰 开始大规模战斗AI性能测试...")

    local scale_results = {}

    for scale_name, scale_config in pairs(AIPerformanceTest.config.battle_scales) do
        local total_time = 0
        local decision_count = 0
        local timeout_count = 0

        for i = 1, 20 do -- 每个规模20次测试
            local battle_state = AIPerformanceTest:create_large_scale_battle_state(scale_config)
            local ai_characters = {}

            -- 为所有AI角色创建AI实例
            for _, character in ipairs(battle_state.characters) do
                if character.team_id ~= 1 then -- 假设队伍1是玩家，其他是AI
                    table.insert(ai_characters, {
                        character = character,
                        ai = TacticalAI:new()
                    })
                end
            end

            -- 性能测试：所有AI同时做决策
            local start_time = os.clock()

            for _, ai_info in ipairs(ai_characters) do
                local decision = ai_info.ai:make_decision(ai_info.character, battle_state)
                decision_count = decision_count + 1
            end

            local end_time = os.clock()
            local total_response_time = (end_time - start_time) * 1000

            if total_response_time > AIPerformanceTest.config.decision_timeout * #ai_characters then
                timeout_count = timeout_count + 1
            end

            total_time = total_time + total_response_time / #ai_characters -- 平均每个AI的响应时间
        end

        local avg_time = total_time / 20

        scale_results[scale_name] = {
            scale = scale_config,
            avg_response_time = avg_time,
            timeout_count = timeout_count,
            decision_count = decision_count
        }
    end

    -- 生成规模性能报告
    local scale_report = "大规模战斗性能报告:\n"
    for scale_name, results in pairs(scale_results) do
        scale_report = scale_report .. string.format(
            "- %s (%d对%d): 平均响应时间 %.2fms, 超时次数 %d\n",
            scale_name, results.scale.players, results.scale.enemies,
            results.avg_response_time, results.timeout_count
        )
    end

    print(scale_report)

    -- 验证大规模性能
    if not (scale_results.large.avg_response_time <= AIPerformanceTest.config.performance_threshold * 2) then
        error("大规模战斗响应时间过长")
    end

    if not (scale_results.large.timeout_count < 5) then
        error("大规模战斗超时次数过多")
    end

    return scale_results
end

-- 辅助函数：创建测试战斗状态
function AIPerformanceTest:create_test_battle_state()
    -- 简化的测试战斗状态创建
    return {
        characters = {
            {
                id = 1,
                name = "测试角色",
                team_id = 1,
                hp = 100,
                max_hp = 100,
                mp = 50,
                max_mp = 50,
                attack = 20,
                defense = 15,
                magic_attack = 18,
                magic_defense = 12,
                speed = 10,
                is_alive = true,
                skills = {
                    {id = 1, name = "普通攻击", damage = {base = 20}, healing = {base = 0}, cost = {mp = 0},
                     is_usable = function(self, character) return character.mp >= (self.cost.mp or 0) end,
                     calculate_damage = function(self, character, target) return self.damage.base end,
                     calculate_healing = function(self, character, target) return self.healing.base end
                    },
                    {id = 2, name = "火球术", damage = {base = 30}, healing = {base = 0}, cost = {mp = 10},
                     is_usable = function(self, character) return character.mp >= (self.cost.mp or 0) end,
                     calculate_damage = function(self, character, target) return self.damage.base end,
                     calculate_healing = function(self, character, target) return self.healing.base end
                    },
                    {id = 3, name = "治疗术", damage = {base = 0}, healing = {base = 25}, cost = {mp = 8},
                     is_usable = function(self, character) return character.mp >= (self.cost.mp or 0) end,
                     calculate_damage = function(self, character, target) return self.damage.base end,
                     calculate_healing = function(self, character, target) return self.healing.base end
                    }
                },
                items = {
                    ["potion"] = 3,
                    ["ether"] = 2
                }
            },
            {
                id = 2,
                name = "敌人",
                team_id = 2,
                hp = 80,
                max_hp = 120,
                mp = 40,
                max_mp = 60,
                attack = 18,
                defense = 12,
                magic_attack = 20,
                magic_defense = 10,
                speed = 12,
                is_alive = true,
                skills = {
                    {id = 1, name = "攻击", damage = {base = 18}, healing = {base = 0}, cost = {mp = 0},
                     is_usable = function(self, character) return character.mp >= (self.cost.mp or 0) end,
                     calculate_damage = function(self, character, target) return self.damage.base end,
                     calculate_healing = function(self, character, target) return self.healing.base end
                    }
                },
                items = {}
            }
        },
        player_team_id = 1,
        current_turn = 1,
        turn_order = {1, 2}
    }
end

-- 辅助函数：创建大规模战斗状态
function AIPerformanceTest:create_large_scale_battle_state(scale_config)
    local battle_state = {
        characters = {},
        player_team_id = 1,
        current_turn = 1,
        turn_order = {}
    }

    -- 创建玩家队伍
    for i = 1, scale_config.players do
        table.insert(battle_state.characters, {
            id = i,
            name = "玩家" .. i,
            team_id = 1,
            hp = 100,
            max_hp = 100,
            mp = 50,
            max_mp = 50,
            attack = 20,
            defense = 15,
            is_alive = true,
            skills = {
                {id = 1, name = "普通攻击", damage = {base = 20}, cost = {mp = 0},
                 is_usable = function(self, character) return character.mp >= (self.cost.mp or 0) end,
                 calculate_damage = function(self, character, target) return self.damage.base end,
                 calculate_healing = function(self, character, target) return self.healing.base end
                }
            },
            items = {}
        })
        table.insert(battle_state.turn_order, i)
    end

    -- 创建敌人队伍
    for i = 1, scale_config.enemies do
        local enemy_id = scale_config.players + i
        table.insert(battle_state.characters, {
            id = enemy_id,
            name = "敌人" .. i,
            team_id = 2,
            hp = 80,
            max_hp = 80,
            mp = 30,
            max_mp = 30,
            attack = 18,
            defense = 12,
            is_alive = true,
            skills = {
                {id = 1, name = "攻击", damage = {base = 18}, cost = {mp = 0},
                 is_usable = function(self, character) return character.mp >= (self.cost.mp or 0) end,
                 calculate_damage = function(self, character, target) return self.damage.base end,
                 calculate_healing = function(self, character, target) return self.healing.base end
                }
            },
            items = {}
        })
        table.insert(battle_state.turn_order, enemy_id)
    end

    return battle_state
end

-- 辅助函数：深拷贝战斗状态
function AIPerformanceTest:deep_copy_battle_state(battle_state)
    -- 简化的深拷贝实现
    local copy = {
        characters = {},
        player_team_id = battle_state.player_team_id,
        current_turn = battle_state.current_turn,
        turn_order = {}
    }

    for i, char in ipairs(battle_state.characters) do
        copy.characters[i] = {
            id = char.id,
            name = char.name,
            team_id = char.team_id,
            hp = char.hp,
            max_hp = char.max_hp,
            mp = char.mp,
            max_mp = char.max_mp,
            attack = char.attack,
            defense = char.defense,
            is_alive = char.is_alive
        }
    end

    for i, id in ipairs(battle_state.turn_order) do
        copy.turn_order[i] = id
    end

    return copy
end

-- 辅助函数：评估决策质量
function AIPerformanceTest:evaluate_decision_quality(battle_state, decision, character)
    if not decision then
        return 0
    end

    local score = 50 -- 基础分数

    -- 根据角色生命值评估决策合理性
    local health_percentage = character.hp / character.max_hp

    if health_percentage < 0.3 then
        -- 低生命值时应该优先治疗或防御
        if decision.type == "skill" and decision.skill and decision.skill.healing and decision.skill.healing.base > 0 then
            score = score + 30
        elseif decision.type == "defend" then
            score = score + 20
        elseif decision.type == "item" then
            score = score + 25
        else
            score = score - 20
        end
    elseif health_percentage > 0.7 then
        -- 高生命值时应该优先攻击
        if decision.type == "skill" and decision.skill and decision.skill.damage and decision.skill.damage.base > 0 then
            score = score + 20
        else
            score = score - 10
        end
    end

    -- 考虑MP使用效率
    if character.mp < character.max_mp * 0.2 then
        -- MP不足时应该优先使用低消耗技能
        if decision.type == "skill" and decision.skill and decision.skill.cost and decision.skill.cost.mp == 0 then
            score = score + 15
        elseif decision.type == "skill" and decision.skill and decision.skill.cost and decision.skill.cost.mp > character.mp then
            score = score - 30 -- 无法使用的技能
        end
    end

    -- 考虑目标选择
    if decision.target and decision.target.team_id ~= character.team_id then
        -- 攻击敌人时选择低生命值目标更好
        local target_health_percentage = decision.target.hp / decision.target.max_hp
        if target_health_percentage < 0.3 then
            score = score + 15
        end
    end

    return math.max(0, math.min(100, score))
end

-- 辅助函数：判断决策是否战略正确
function AIPerformanceTest:is_strategically_correct(battle_state, decision)
    if not decision then
        return false
    end

    -- 简化的战略正确性判断
    -- 这里可以根据实际游戏逻辑进行更复杂的判断

    return true -- 暂时返回true，实际应用中需要具体实现
end

-- 主测试函数
function AIPerformanceTest.run_all_tests()
    print("🚀 开始AI系统性能全面测试...")
    print("=" .. string.rep("=", 50))

    local test_results = {}

    -- 执行所有测试
    test_results.response_time = AIPerformanceTest.test_decision_response_time()
    print("\n" .. string.rep("-", 50))

    test_results.quality = AIPerformanceTest.test_decision_quality()
    print("\n" .. string.rep("-", 50))

    test_results.memory = AIPerformanceTest.test_memory_leaks()
    print("\n" .. string.rep("-", 50))

    test_results.difficulty = AIPerformanceTest.test_difficulty_performance()
    print("\n" .. string.rep("-", 50))

    test_results.scale = AIPerformanceTest.test_large_scale_performance()

    -- 生成综合报告
    AIPerformanceTest:generate_comprehensive_report(test_results)

    return test_results
end

-- 生成综合报告
function AIPerformanceTest:generate_comprehensive_report(test_results)
    print("\n" .. "=" .. string.rep("=", 50))
    print("📊 AI系统性能综合评估报告")
    print("=" .. string.rep("=", 50))

    -- 响应时间评估
    local response_grade = "优秀"
    if test_results.response_time.avg_response_time > 100 then
        response_grade = "需优化"
    elseif test_results.response_time.avg_response_time > 50 then
        response_grade = "良好"
    end

    -- 决策质量评估
    local quality_grade = "优秀"
    if test_results.quality.avg_decision_score < 60 then
        quality_grade = "需优化"
    elseif test_results.quality.avg_decision_score < 80 then
        quality_grade = "良好"
    end

    -- 内存泄漏评估
    local memory_grade = "优秀"
    if test_results.memory.has_leak then
        memory_grade = "需优化"
    end

    -- 综合评分
    local overall_score = 0
    overall_score = overall_score + (test_results.response_time.passed_tests / test_results.response_time.total_tests) * 30
    overall_score = overall_score + (test_results.quality.efficiency_score / 100) * 40
    overall_score = overall_score + (test_results.memory.has_leak and 0 or 1) * 30

    local overall_grade = "优秀"
    if overall_score < 60 then
        overall_grade = "需优化"
    elseif overall_score < 80 then
        overall_grade = "良好"
    end

    print(string.format([[
📈 性能指标评估:
- 响应时间: %s (平均 %.2fms)
- 决策质量: %s (评分 %.1f/100)
- 内存管理: %s (%s泄漏)
- 综合评分: %.1f/100 (%s)

🎯 优化建议:
%s
    ]],
        response_grade, test_results.response_time.avg_response_time,
        quality_grade, test_results.quality.avg_decision_score,
        memory_grade, test_results.memory.has_leak and "检测到" or "无",
        overall_score, overall_grade,
        AIPerformanceTest:get_optimization_suggestions(test_results)
    ))
end

-- 获取优化建议
function AIPerformanceTest:get_optimization_suggestions(test_results)
    local suggestions = {}

    if test_results.response_time.avg_response_time > 50 then
        table.insert(suggestions, "- 优化AI决策算法，减少计算复杂度")
        table.insert(suggestions, "- 考虑实现决策缓存机制")
    end

    if test_results.quality.avg_decision_score < 70 then
        table.insert(suggestions, "- 改进AI策略权重配置")
        table.insert(suggestions, "- 增强AI对战斗状态的理解")
    end

    if test_results.memory.has_leak then
        table.insert(suggestions, "- 修复内存泄漏问题")
        table.insert(suggestions, "- 优化对象生命周期管理")
    end

    if #suggestions == 0 then
        return "✅ AI系统性能表现优秀，暂无优化建议"
    else
        return table.concat(suggestions, "\n")
    end
end

-- 添加测试到套件
suite:add_test("AI决策响应时间测试", AIPerformanceTest.test_decision_response_time)
suite:add_test("AI决策质量评估", AIPerformanceTest.test_decision_quality)
suite:add_test("内存泄漏检测", AIPerformanceTest.test_memory_leaks)
suite:add_test("难度级别性能对比", AIPerformanceTest.test_difficulty_performance)
suite:add_test("大规模战斗性能测试", AIPerformanceTest.test_large_scale_performance)

-- 主程序
if arg and arg[0] and arg[0]:match("ai_performance_test%.lua$") then
    print("开始运行AI性能测试...")

    local results = AIPerformanceTest.run_all_tests()

    print("\n🎉 AI性能测试完成！")
end

-- 导出模块
return {
    AIPerformanceTest = AIPerformanceTest,
    run_tests = function() return AIPerformanceTest.run_all_tests() end,
    test_suite = suite
}